package com.zq.learn.akka.typed;

import akka.actor.typed.ActorRef;
import akka.actor.typed.Behavior;
import akka.actor.typed.javadsl.AbstractBehavior;
import akka.actor.typed.javadsl.ActorContext;
import akka.actor.typed.javadsl.Behaviors;
import akka.actor.typed.javadsl.Receive;

/**
 * 问候Actor
 *
 * Actor默认是被挂起的，直到被消息驱动。
 * Actor采用异步消息机制:
 * 消息发送者(sender)——>邮箱（mailbox）——>Actor.
 *
 * @author ZhangQi
 * @date 2020/3/13
 */
public class Greeter extends AbstractBehavior<Greeter.Greet> {
  /**
   * 问候——消息
   */
  public static final class Greet {
    public final String whom;
    public final ActorRef<Greeted> replyTo;

    public Greet(String whom,ActorRef<Greeted> replyTo){
      this.whom=whom;
      this.replyTo=replyTo;
    }

  }

  /**
   * 返回问候——消息
   */
  public static final class Greeted {
    public final String whom;
    public final ActorRef<Greet> from;

    public Greeted(String whom, ActorRef<Greet> from) {
      this.whom = whom;
      this.from = from;
    }
  }

  /**
   * 向外部提供创建方法
   * @return
   */
  public static Behavior<Greet> create(){
    return Behaviors.setup(Greeter::new);
  }
  /**
   * 私有构造
   * @param context
   */
  private Greeter(ActorContext<Greet> context) {
    super(context);
  }

  /**
   * 接收方法（重写）
   *
   * @return
   */
  @Override
  public Receive<Greet> createReceive() {
    //处理消息
    return newReceiveBuilder().onMessage(Greet.class,this::onGreet).build();
  }

  /**
   * 收到问候处理
   * @param command
   * @return
   */
  private  Behavior<Greet> onGreet(Greet command) {
    getContext().getLog().info("Hello {}!",command.whom);
    //推送消息
    command.replyTo.tell(new Greeted(command.whom,getContext().getSelf()));
    return this;
  }

}
